#include "MicroKB.h"
#include "A_Config.h"
MicroKB microKB;
static void task_MicroKB(void *)
{
    while (1)
    {
        microKB.update();
        vTaskDelay(20);
    }
}
bool MicroKB::isConnected()
{
    uint8_t errors = 0;
    for (uint8_t i = 0; i < 4; ++i)
    {
        Wire1.beginTransmission(MICROKB_ADDR);
        errors += Wire1.endTransmission() == 0 ? 0 : 1;
    }
    if (errors >= 3)
    {
        running = false;
        return false;
    }
    running = true;
    return true;
}

void MicroKB::update()
{
    if (running == false)
        return;
    Wire1.beginTransmission(MICROKB_ADDR);
    Wire1.write(60);
    Wire1.endTransmission();
    Wire1.requestFrom(MICROKB_ADDR, 1);
    char c = Wire1.read();
    bool pressed = true;
    if (c == 0xff)
        return;
    if (c >= 0x80)
    {
        c &= 0x7f;
        pressed = false;
    }
    if (keyCodeToChar[c] == ESC)
    {
        isESC = pressed;
    }
    else if (keyCodeToChar[c] == SHIFT)
    {
        isShift = pressed;
    }
    else if (keyCodeToChar[c] == ALT)
    {
        isAlt = pressed;
    }
    else if (keyCodeToChar[c] == CTRL)
    {
        isCtrl = pressed;
    }
    else if (pressed == true)
    {
        char input;
        if (isShift == true)
        {
            input = keyCodeToCharShifted[c];
        }
        else
        {
            input = keyCodeToChar[c];
        }
        xQueueSend(queue, &input, portMAX_DELAY);
    }
}
void MicroKB::begin()
{
    queue = xQueueCreate(64, sizeof(char));
    if (queue == NULL)
    {
        Serial.println("[MicroKB] 错误：无法创建队列");
        delay(100);
        ESP.restart();
    }
    xTaskCreatePinnedToCore(task_MicroKB, "task_MicroKB", 2048, NULL, configMAX_PRIORITIES - 1, NULL, !CONFIG_ARDUINO_RUNNING_CORE);
}
char MicroKB::getChar(uint32_t timeout)
{
    char element = 0;
    xQueueReceive(queue, &element, timeout);
    return element;
}